package com.sea.base.json.typeAdapter

import com.google.gson.JsonElement
import com.google.gson.JsonNull
import com.google.gson.JsonPrimitive
import com.google.gson.TypeAdapter
import com.google.gson.internal.Streams
import com.google.gson.stream.JsonReader

internal inline fun <T> TypeAdapter<*>.tryThrow(inReader: JsonReader?, json: Any?, typeName: String, call: () -> T): T {
    return try {
        call()
    } catch (e: Exception) {
        e.printStackTrace()
        return throwE(inReader, json, typeName, e)
    }
}

internal fun <T> TypeAdapter<*>.throwE(inReader: JsonReader?, json: Any?, typeName: String, e: Throwable? = null): T {
    throw MyJsonParseException("key：${inReader?.path}，value：$json，无法转换为$typeName", e)
}

/**
 * 读取建议的double值，不可转为int或long
 */
internal inline fun <T : Number> TypeAdapter<out Number>.readNumber(
    inReader: JsonReader?,
    typeName: String,
    onToNumber: (String) -> T,
    onAsNumber: (JsonElement) -> T,
): T? {
    when (val je = Streams.parse(inReader)) {
        is JsonNull -> {
            return null
        }

        is JsonPrimitive -> {
            if (je.isString) {
                return when (val stValue = je.asString) {
                    null, "", "null", "Null", "NULL" -> {
                        null
                    }

                    else -> {
                        tryThrow(inReader, je, typeName) { onToNumber.invoke(stValue) }
                    }
                }
            }
            return tryThrow(inReader, je, typeName) { onAsNumber.invoke(je) }
        }

        else -> {
            return throwE(inReader, je, typeName)
        }
    }
}

class MyJsonParseException(msg: String? = null, e: Throwable? = null) : IllegalStateException(msg, e)